package com.nulldev.util.web.YouTubeExtractor.comments.handlers;

import static com.nulldev.util.web.YouTubeExtractor.extractors.util.SharedExtractorUtil.YTX_GET_MUTATION_IDENTIFIER;

import java.util.List;

import com.nulldev.util.JVM.Arguments;
import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.web.YouTubeExtractor.comments.YTComment;

public class CVMCommentHandler {

	private static final Logger logger = LoggerFactory.getLoggerD(Arguments.hasArgument("--debug", "--YTComments.debug", "--trace"));

	public static void __process_key_based_comments(final UniJsonValue obj, final UniJsonValue comment, final List<YTComment> comments) {
		final UniJsonValue frameworkUpdates = obj.get("frameworkUpdates");
		if (frameworkUpdates == null) {
			logger.error("Failed to find frameworkUpdates in obj!");
			logger.derror("payload: " + obj);
			return;
		}
		final UniJsonValue entityBatchUpdate = frameworkUpdates.get("entityBatchUpdate");
		if (entityBatchUpdate == null) {
			logger.error("Failed to find entityBatchUpdates in frameworkUpdates!");
			logger.derror("payload: " + obj);
			return;
		}
		final UniJsonValue mutations = entityBatchUpdate.get("mutations").asArray();
//
		final UniJsonValue commentThreadRenderer;
		final UniJsonValue commentViewModel;
		if (comment.contains("commentThreadRenderer")) {
			commentThreadRenderer = comment.get("commentThreadRenderer");
			/* Why is it duplicated twice!?!?!?!?!?!??!?! */
			commentViewModel = commentThreadRenderer.get("commentViewModel").get("commentViewModel");
		} else {
			commentThreadRenderer = comment;
			commentViewModel = commentThreadRenderer.get("commentViewModel");
		}

		if (commentViewModel == null) {
			logger.error("Failed to find commentViewModel in commentThreadRenderer!");
			logger.derror("payload: " + comment);
			return;
		}
		final String commentKey = commentViewModel.getString("commentKey");
//
		final UniJsonValue _mutation = YTX_GET_MUTATION_IDENTIFIER(mutations, commentKey);
		if (_mutation == null) {
			logger.error("Failed to find mutation!");
			logger.derror("commentKey: " + commentKey);
			return;
		}
		if (!_mutation.contains("payload")) {
			logger.error("Failed to find payload in _mutation!");
			logger.derror("payload: " + _mutation);
			return;
		}
		final UniJsonValue mutation = _mutation.get("payload");
		if (!mutation.contains("commentEntityPayload")) {
			logger.error("Failed to find commentEntityPayload in mutation!");
			logger.derror("payload: " + mutation);
			return;
		}

		final UniJsonValue commentEntityPayload = mutation.get("commentEntityPayload");

		final UniJsonValue author = commentEntityPayload.get("author");
		final UniJsonValue toolbar = commentEntityPayload.get("toolbar");
		final UniJsonValue properties = commentEntityPayload.get("properties");
		final UniJsonValue content = properties.get("content");

		final String authorName = author.getString("displayName");
		final String authorThumbnail = author.getString("avatarThumbnailUrl");
		final String commentText = content.getString("content");
		final long replyCount = MathUtil.safeParseL(toolbar.getString("replyCount"), 0);
		long likeCount = MathUtil.safeParseL(toolbar.getString("likeCountNotliked"), 0);

		String repliesCont = null;
		/*
		 * I love having to look through two different objects just to piece together
		 * things
		 */
		if (commentThreadRenderer.contains("replies")) {
			final UniJsonValue replies = commentThreadRenderer.get("replies");
			if (replies.contains("commentRepliesRenderer")) {
				final UniJsonValue commentRepliesRenderer = replies.get("commentRepliesRenderer");
				if (commentRepliesRenderer.contains("contents")) {
					final UniJsonValue contents = commentRepliesRenderer.get("contents").asArray();
					final UniJsonValue firstItem = contents.first();
					if (firstItem == null || firstItem.isNull()) {
						logger.error("Invalid commentRepliesRenderer contents!");
						logger.derror("contents: " + contents);
					} else if (!firstItem.contains("continuationItemRenderer")) {
						logger.warn("Unknown commentRepliesRenderer contents!");
						logger.dwarn("contents: " + contents);
					} else {
						final UniJsonValue continutationItemRenderer = firstItem.get("continuationItemRenderer");
						repliesCont = continutationItemRenderer.get("continuationEndpoint").get("continuationCommand").getString("token");
					}
				} else {
					logger.warn("Unknown commentRepliesRenderer object!");
					logger.dwarn("commentRepliesRenderer: " + commentRepliesRenderer);
				}
			} else {
				logger.warn("Unknown replies object!");
				logger.dwarn("replies: " + replies);
			}
		}

		// XXX: These require querying ANOTHER FUCKING MUTATION AAAAAAAAAAAAAAAA.
		final boolean isAuthorLiked = false; // o.getBoolean("isLiked");
		final boolean hasCreatorHeart = false; // __hasCreatorHeart(o);
		final boolean isPinned = false;
		final boolean isVerified = author.bool("isVerified");

		comments.add(new YTComment(authorName, authorThumbnail, isAuthorLiked, hasCreatorHeart, isPinned, commentText, repliesCont, likeCount, replyCount,
				isVerified));
	}
}
